package com.frogs.ucenter.v1.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONObject;
import com.frogs.framework.util.PageList;
import com.frogs.framework.util.StringUtil;
import com.frogs.framework.util.date.DateUtil;
import com.frogs.system.util.AttentionStateEnum;
import com.frogs.system.util.TaskActionShowStatusEnum;
import com.frogs.system.util.TaskActionStatusEnum;
import com.frogs.system.util.TaskCompleteStatusEnum;
import com.frogs.system.util.TaskCycleEnum;
import com.frogs.system.util.TaskGetStrategyEnum;
import com.frogs.system.util.TaskTypeEnum;
import com.frogs.system.web.api.request.Request;
import com.frogs.system.web.api.response.Response;
import com.frogs.system.web.exception.ServiceOperationException;
import com.frogs.ucenter.component.GivingAsyncHelper;
import com.frogs.ucenter.dao.ActionLogDao;
import com.frogs.ucenter.dao.FlowTaskCompleteInfoDao;
import com.frogs.ucenter.dao.PointTaskCompleteInfoDao;
import com.frogs.ucenter.dao.SubFlowCompleteInfoDao;
import com.frogs.ucenter.dao.SubFlowInfoDao;
import com.frogs.ucenter.dao.SubFlowTaskRelationDao;
import com.frogs.ucenter.dao.TaskInfoDao;
import com.frogs.ucenter.dao.TotalFlowCompleteInfoDao;
import com.frogs.ucenter.dao.TotalFlowInfoDao;
import com.frogs.ucenter.dao.TotalFlowRelationDao;
import com.frogs.ucenter.dao.UserAttentionInfoDao;
import com.frogs.ucenter.entity.ActionLog;
import com.frogs.ucenter.entity.GivingInfo;
import com.frogs.ucenter.entity.PointTaskCompleteInfo;
import com.frogs.ucenter.entity.TaskInfo;
import com.frogs.ucenter.entity.TaskInfoWithPointTaskCompleteInfo;
import com.frogs.ucenter.entity.ext.UserAttentionInfoExt;
import com.frogs.ucenter.v1.request.ActionLogRequest;
import com.frogs.ucenter.v1.request.PointTaskInfoListRequest;
import com.frogs.ucenter.v1.request.TaskCompleteRequest;
import com.frogs.ucenter.v1.response.DefaultResponse;
import com.frogs.ucenter.v1.response.ListResponse;
import com.frogs.ucenter.v1.response.PageListResponse;
import com.frogs.ucenter.v1.service.TaskService;
import com.frogs.ucenter.v1.util.ApiConstants;

/**
 * 任务逻辑处理类
 *
 * @author lijian
 * @version 2014年10月20日 - 上午9:54:39
 */
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class) 
@Service(ApiConstants.VERSION+"taskService")
public class TaskServiceImpl implements TaskService {

	private static final Logger log = LoggerFactory.getLogger(TaskServiceImpl.class);
	
	@Resource
	private TotalFlowInfoDao totalFlowInfoDao;
	@Resource
	private SubFlowInfoDao subFlowInfoDao;
	@Resource
	private TaskInfoDao taskInfoDao;
	@Resource
	private TotalFlowCompleteInfoDao totalFlowCompleteInfoDao;
	@Resource
	private SubFlowCompleteInfoDao subFlowCompleteInfoDao;
	@Resource
	private FlowTaskCompleteInfoDao flowTaskCompleteInfoDao;
	@Resource
	private PointTaskCompleteInfoDao pointTaskCompleteInfoDao;
	@Resource
	private TotalFlowRelationDao totalFlowRelationDao;
	@Resource
	private SubFlowTaskRelationDao subFlowTaskRelationDao;
	@Resource
	private ActionLogDao actionLogDao;
	@Resource
	private UserAttentionInfoDao userAttentionInfoDao;
	@Resource
	private GivingAsyncHelper givingAsyncHelper;
	
	/*********************************************新模块设计**********************************************/
	/**
	 * 
	 * 获取用户所有的常规任务
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@Override
	public Response getUserPointTask(Request request) throws Exception {
		PageListResponse<TaskInfoWithPointTaskCompleteInfo> response = new PageListResponse<TaskInfoWithPointTaskCompleteInfo>();
		try {
			PointTaskInfoListRequest taskInfoListRequest = (PointTaskInfoListRequest) request;
			Integer openPlatformId = taskInfoListRequest.getOpenPlatformId();
			Integer userId = taskInfoListRequest.getUserId();
			// 获取所有的常规任务
			Integer pageNo = taskInfoListRequest.getPageNo();
			Integer pageSize = taskInfoListRequest.getPageSize();
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("eqTaskType", TaskTypeEnum.POINTTASK.getId());
			params.put("eqStatus", TaskActionStatusEnum.ENABLED.getId());
			params.put("leStartTime", new Date());
			params.put("geEndTime", new Date());
			params.put("eqOpenPlatformId", openPlatformId);
			params.put("eqShowStatus", TaskActionShowStatusEnum.YES.getId());
			if (!StringUtil.isEmpty(taskInfoListRequest.getActionType())) {
				params.put("notInActionTypes", taskInfoListRequest.getActionType());
			}
			PageList<TaskInfo> list = taskInfoDao.selectByMap(params, 1, 20);
			List<TaskInfoWithPointTaskCompleteInfo> result = new ArrayList<TaskInfoWithPointTaskCompleteInfo>();
			for (TaskInfo taskInfo : list) {
				Integer cycle = taskInfo.getCycle();
				if (cycle == TaskCycleEnum.EVERYDAY.getId()) {
					result.add(this.getPointTaskByEveryDay(taskInfo, userId));
				} else if (cycle == TaskCycleEnum.NOCODITION.getId()) {
					result.add(this.getPointTaskByNoCodition(taskInfo, userId));
				} else if (cycle == TaskCycleEnum.ONCE.getId()) {
					result.add(this.getPointTaskByOnce(taskInfo, userId));
				} else if (cycle == TaskCycleEnum.WEEKLY.getId()) {
					result.add(this.getPointTaskByWeekly(taskInfo, userId));
				} else if (cycle == TaskCycleEnum.MONTHLY.getId()) {
					result.add(this.getPointTaskByMonthly(taskInfo, userId));
				} else if (cycle == TaskCycleEnum.CONTINUOUS.getId()) {
					result.add(this.getPointTaskByContinuous(taskInfo, userId));
				}
			}
			Collections.sort(result, new Comparator<TaskInfoWithPointTaskCompleteInfo>(){  
	            public int compare(TaskInfoWithPointTaskCompleteInfo arg0, TaskInfoWithPointTaskCompleteInfo arg1) {  
	                return arg0.getCompleteStatus().compareTo(arg1.getCompleteStatus());  
	            }  
	        });
			response.setList(result);
			response.setPageTurn(list.getPageTurn());
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}
	
	/**
	 * 获取每天连续执行的常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByContinuous(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("orderByClause", "pointTaskCompleteInfoId desc");
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list != null && list.size() > 0) {
			completeInfo = list.get(0);
		} else {
			completeInfo = insertPointTask(taskInfo, userId);
		}
		if (completeInfo.getStatus() != TaskCompleteStatusEnum.FINISH.getId()) {
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				if (!DateUtil.formatDate(new Date(), "yyyy-MM-dd").equals(DateUtil.formatDate(completeInfo.getLastDate(), "yyyy-MM-dd"))) {
					completeInfo = insertPointTask(taskInfo, userId);
				}
			}
		}
		int days = DateUtil.getIntervalDays(completeInfo.getLastDate(), new Date());
		if (days > 1) {
			completeInfo.setCompleteDays(0);
			PointTaskCompleteInfo pointTaskCompleteInfo = pointTaskCompleteInfoDao.selectById(completeInfo.getPointTaskCompleteInfoId());
			pointTaskCompleteInfo.setCompleteDays(0);
			pointTaskCompleteInfo.setLastDate(new Date());
			pointTaskCompleteInfoDao.update(pointTaskCompleteInfo);
		} else {
			completeInfo.setCompleteDays(completeInfo.getCompleteDays());
		}
		return completeInfo;
	}
	
	/**
	 * 获取每天的常规任务
	 * @throws Exception 
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByEveryDay(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtUserCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByNoCodition(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByOnce(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list != null && list.size() > 0) {
			completeInfo = list.get(0);
		} else {
			completeInfo = insertPointTask(taskInfo, userId);
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByWeekly(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfWeek(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getFirstDayOfWeek(), 7), "yyyy-MM-dd");
		params.put("gtUserCreateTime", firstDay);
		params.put("ltUserCreateTime", endDay);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
		}
		return completeInfo;
	}
	
	/**
	 * 获取每月常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskByMonthly(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfMonth(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getLastDayOfMonth(), 1), "yyyy-MM-dd");
		params.put("gtUserCreateTime", firstDay);
		params.put("ltUserCreateTime", endDay);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
		}
		return completeInfo;
	}
	
	/**
	 * 获取用户正在进行中和已完成的常规任务
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@Override
	public Response getUserPointTaskByOther(Request request) throws Exception {
		ListResponse<TaskInfoWithPointTaskCompleteInfo> response = new ListResponse<TaskInfoWithPointTaskCompleteInfo>();
		try {
			PointTaskInfoListRequest taskInfoListRequest = (PointTaskInfoListRequest) request;
			List<TaskInfoWithPointTaskCompleteInfo> result = this.getUserPointTask(taskInfoListRequest);
			response.setList(result);
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}
	
	private List<TaskInfoWithPointTaskCompleteInfo> getUserPointTask(PointTaskInfoListRequest taskInfoListRequest) throws Exception {
		// 获取所有的常规任务
		Integer openPlatformId = taskInfoListRequest.getOpenPlatformId();
		Integer userId = taskInfoListRequest.getUserId();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqTaskType", TaskTypeEnum.POINTTASK.getId());
		params.put("eqStatus", TaskActionStatusEnum.ENABLED.getId());
		params.put("leStartTime", new Date());
		params.put("geEndTime", new Date());
		params.put("eqOpenPlatformId", openPlatformId);
		params.put("eqShowStatus", TaskActionShowStatusEnum.YES.getId());
		if (!StringUtil.isEmpty(taskInfoListRequest.getActionType())) {
			params.put("notInActionTypes", taskInfoListRequest.getActionType());
		}
		PageList<TaskInfo> list = taskInfoDao.selectByMap(params, 1, 1000);
		List<TaskInfoWithPointTaskCompleteInfo> result = new ArrayList<TaskInfoWithPointTaskCompleteInfo>();
		for (TaskInfo taskInfo : list) {
			Integer cycle = taskInfo.getCycle();
			TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
			if (cycle == TaskCycleEnum.EVERYDAY.getId()) {
				completeInfo = this.getPointTaskOtherByEveryDay(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			} else if (cycle == TaskCycleEnum.NOCODITION.getId()) {
				completeInfo = this.getPointTaskOtherByNoCodition(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			} else if (cycle == TaskCycleEnum.ONCE.getId()) {
				completeInfo = this.getPointTaskOtherByOnce(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			} else if (cycle == TaskCycleEnum.WEEKLY.getId()) {
				completeInfo = this.getPointTaskOtherByWeekly(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			} else if (cycle == TaskCycleEnum.MONTHLY.getId()) {
				completeInfo = this.getPointTaskOtherByMonthly(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			} else if (cycle == TaskCycleEnum.CONTINUOUS.getId()) {
				completeInfo = this.getPointTaskOtherByContinuous(taskInfo, userId);
				if (completeInfo != null) {
					result.add(completeInfo);
				}
			}
		}
		return result;
	}
	
	/**
	 * 获取每天连续执行的常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByContinuous(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("orderByClause", "pointTaskCompleteInfoId desc");
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list != null && list.size() > 0) {
			completeInfo = list.get(0);
		} else {
			completeInfo = insertPointTask(taskInfo, userId);
		}
		if (completeInfo.getStatus() != TaskCompleteStatusEnum.FINISH.getId()) {
			if (completeInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				if (!DateUtil.formatDate(new Date(), "yyyy-MM-dd").equals(DateUtil.formatDate(completeInfo.getLastDate(), "yyyy-MM-dd"))) {
					completeInfo = insertPointTask(taskInfo, userId);
				} else {
					return null;
				}
			}
		}
		int days = DateUtil.getIntervalDays(completeInfo.getLastDate(), new Date());
		if (days > 1) {
			completeInfo.setCompleteDays(0);
			PointTaskCompleteInfo pointTaskCompleteInfo = pointTaskCompleteInfoDao.selectById(completeInfo.getPointTaskCompleteInfoId());
			pointTaskCompleteInfo.setCompleteDays(0);
			pointTaskCompleteInfo.setLastDate(new Date());
			pointTaskCompleteInfoDao.update(pointTaskCompleteInfo);
		} else {
			completeInfo.setCompleteDays(completeInfo.getCompleteDays());
		}
		return completeInfo;
	}
	
	/**
	 * 获取每天的常规任务
	 * @throws Exception 
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByEveryDay(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		params.put("gtUserCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getCompleteStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				return null;
			}
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByNoCodition(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getCompleteStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				return null;
			}
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByOnce(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list != null && list.size() > 0) {
			completeInfo = list.get(0);
			if (completeInfo.getCompleteStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				return null;
			}
		} else {
			completeInfo = insertPointTask(taskInfo, userId);
		}
		return completeInfo;
	}
	
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByWeekly(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfWeek(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getFirstDayOfWeek(), 7), "yyyy-MM-dd");
		params.put("gtUserCreateTime", firstDay);
		params.put("ltUserCreateTime", endDay);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getCompleteStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				return null;
			}
		}
		return completeInfo;
	}
	
	/**
	 * 获取每月常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private TaskInfoWithPointTaskCompleteInfo getPointTaskOtherByMonthly(TaskInfo taskInfo, Integer userId) throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", taskInfo.getId());
		params.put("eqUserId", userId);
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfMonth(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getLastDayOfMonth(), 1), "yyyy-MM-dd");
		params.put("gtUserCreateTime", firstDay);
		params.put("ltUserCreateTime", endDay);
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		TaskInfoWithPointTaskCompleteInfo completeInfo = new TaskInfoWithPointTaskCompleteInfo();
		if (list.size() == 0) {
			completeInfo = insertPointTask(taskInfo, userId);
		} else {
			completeInfo = list.get(0);
			if (completeInfo.getCompleteStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
				return null;
			}
		}
		return completeInfo;
	}
	
	/**
	 * 插入常规任务
	 * 
	 * @param taskInfo
	 * @param userId
	 * @throws Exception 
	 */
	private TaskInfoWithPointTaskCompleteInfo insertPointTask(TaskInfo taskInfo, Integer userId) throws Exception {
		PointTaskCompleteInfo pointTaskCompleteInfo = new PointTaskCompleteInfo();
		Date date = new Date();
		pointTaskCompleteInfo.setCreateTime(date);
		pointTaskCompleteInfo.setTaskId(taskInfo.getId());
		pointTaskCompleteInfo.setUserId(userId);
		pointTaskCompleteInfo.setLastDate(date);
		pointTaskCompleteInfo.setCompleteNum(0);
		pointTaskCompleteInfo.setNumberUpperLimit(taskInfo.getNumberUpperLimit());
		pointTaskCompleteInfo.setStatus(TaskCompleteStatusEnum.PROCESSING.getId());
		pointTaskCompleteInfoDao.insert(pointTaskCompleteInfo);
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqTaskCompleteId", pointTaskCompleteInfo.getId());
		PageList<TaskInfoWithPointTaskCompleteInfo> list = taskInfoDao.selectWithPointTaskCompletionByMap(params, 1, 100);
		return list.get(0);
	}
	
	/**
	 * 获取家庭成员正在进行中和已完成的常规任务
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@Override
	public Response getAttentionPointTask(Request request) throws Exception {
		PageListResponse<JSONObject> response = new PageListResponse<JSONObject>();
		try {
			PointTaskInfoListRequest taskInfoListRequest = (PointTaskInfoListRequest) request;
			Integer userId = taskInfoListRequest.getUserId();
			
			HashMap<String,Object> params = new HashMap<String,Object>();
    		params.put("eqFollowUserId", userId);
    		params.put("eqStatus", AttentionStateEnum.ATTENTION_STATUS_AGREED.getId() );
    		params.put("orderByClause"," id DESC" );
    		//我关注的人的列表
    		PageList<UserAttentionInfoExt> list = userAttentionInfoDao.selectByMapForAttention(params, taskInfoListRequest.getPageNo(), taskInfoListRequest.getPageSize());
    		List<JSONObject> array = new ArrayList<JSONObject>();
    		for (UserAttentionInfoExt userAttentionInfoExt : list) {
    			JSONObject object = new JSONObject();
				Integer followedUserId = userAttentionInfoExt.getFollowedUserId();
				taskInfoListRequest.setUserId(followedUserId);
				object.put("userInfo", userAttentionInfoExt);
				object.put("taskInfo", this.getUserPointTask(taskInfoListRequest));
				array.add(object);
    		}
    		response.setList(array);
    		response.setPageTurn(list.getPageTurn());
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}
	
	/**
	 * 领取常规任务奖励
	 */
	@Override
	public Response completePointTask(Request request) throws Exception  {
		DefaultResponse response = new DefaultResponse();
		try {
			TaskCompleteRequest taskCompleteRequest = (TaskCompleteRequest) request;
			Integer taskCompleteInfoId = taskCompleteRequest.getTaskCompleteInfoId();
			Integer userId = taskCompleteRequest.getUserId();
			String expandCode = taskCompleteRequest.getExpandCode();
			Integer applicablePlatformId = taskCompleteRequest.getApplicablePlatformId();
			this.completePointTask(taskCompleteInfoId, userId, expandCode, applicablePlatformId);
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException(e.getMessage());
		}
		return response;
	}
	
	/**
	 * 完成常规任务
	 * 
	 * @param taskInfoId
	 * @param userId
	 * @param object
	 */
	private void completePointTask(Integer taskCompleteInfoId, int userId, String expandCode, Integer applicablePlatformId)  throws Exception {
		PointTaskCompleteInfo pointTaskCompleteInfo = pointTaskCompleteInfoDao.selectById(taskCompleteInfoId);
		if (userId != pointTaskCompleteInfo.getUserId()) {
			throw new ServiceOperationException("该任务不存在");
		}
		if (pointTaskCompleteInfo.getStatus() == TaskCompleteStatusEnum.COMPLETED.getId()) {
			throw new ServiceOperationException("该任务奖励已领取完");
		}
		TaskInfo taskInfo = taskInfoDao.selectById(pointTaskCompleteInfo.getTaskId());
		Integer cycle = taskInfo.getCycle();
		if (taskInfo.getStartTime().getTime() > new Date().getTime()) {
			throw new ServiceOperationException("该任务尚未开始");
		}
		if (taskInfo.getEndTime().getTime() < new Date().getTime()) {
			throw new ServiceOperationException("该任务已经结束");
		}
		if (taskInfo.getGetStrategy() == TaskGetStrategyEnum.LIMITED.getId()) {
			if (taskInfo.getGetNum() == 0) {
				throw new ServiceOperationException("该任务奖励已被领取完");
			}
		}
		if (cycle == TaskCycleEnum.ONCE.getId()) {
			this.completePointByOnce(taskInfo, pointTaskCompleteInfo);
		} else if (cycle == TaskCycleEnum.EVERYDAY.getId()) {
			this.completePointByEveryDay(taskInfo, pointTaskCompleteInfo);
		} else if (cycle == TaskCycleEnum.NOCODITION.getId()) {
			this.completePointByNoCondition(taskInfo, pointTaskCompleteInfo);
		} else if (cycle == TaskCycleEnum.WEEKLY.getId()) {
			this.completePointByWeekly(taskInfo, pointTaskCompleteInfo);
		} else if (cycle == TaskCycleEnum.MONTHLY.getId()) {
			this.completePointByMonthly(taskInfo, pointTaskCompleteInfo);
		} else if (cycle == TaskCycleEnum.CONTINUOUS.getId()) {
			this.completePointByContnuous(taskInfo, pointTaskCompleteInfo);
		} else {
			throw new ServiceOperationException("该任务周期不合法");
		}
		GivingInfo givingInfo = givingAsyncHelper.setGivingInfo(taskInfo, userId);
		givingAsyncHelper.giving(givingInfo);
	}
	
	private void completePointByContnuous(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo) throws Exception  {
		if (pointTaskCompleteInfo.getCompleteDays().equals(taskInfo.getDays())) {
			// 更新该常规任务
			updatePointTask(pointTaskCompleteInfo, taskInfo);
		} else {
			throw new ServiceOperationException("该任务未完成");
		}
		
	}
	
	private void completePointByOnce(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo) throws Exception  {
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		if (pointTaskCompleteInfo.getNumberUpperLimit() == 0) {
			throw new ServiceOperationException("该任务领取过奖励");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqUserId", pointTaskCompleteInfo.getUserId());
		params.put("gtCreateTime", taskInfo.getStartTime());
		params.put("leCreateTime", taskInfo.getEndTime());
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum) {
			throw new ServiceOperationException("本任务动作要求次数不足" + completeNum + "次");
		}
		// 更新该常规任务
		updatePointTask(pointTaskCompleteInfo, taskInfo);
	}
	
	private void completePointByEveryDay(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo)  throws Exception {
		Integer numberUpperLimit = taskInfo.getNumberUpperLimit();
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		if (pointTaskCompleteInfo.getNumberUpperLimit() == 0) {
			throw new ServiceOperationException("该任务完成的次数已达到上限");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqUserId", pointTaskCompleteInfo.getUserId());
		params.put("gtCreateTime", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum*(numberUpperLimit-pointTaskCompleteInfo.getNumberUpperLimit()+1)) {
			throw new ServiceOperationException("该操作次数不足");
		}
		// 更新该常规任务
		updatePointTask(pointTaskCompleteInfo, taskInfo);
	}
	
	private void completePointByNoCondition(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo)  throws Exception {
		Integer numberUpperLimit = taskInfo.getNumberUpperLimit();
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		if (pointTaskCompleteInfo.getNumberUpperLimit() == 0) {
			throw new ServiceOperationException("该任务完成的次数已达到上限");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqUserId", pointTaskCompleteInfo.getUserId());
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum*(numberUpperLimit-pointTaskCompleteInfo.getNumberUpperLimit()+1)) {
			throw new ServiceOperationException("该操作次数不足");
		}
		// 更新该常规任务
		updatePointTask(pointTaskCompleteInfo, taskInfo);
	}
	
	private void completePointByWeekly(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo)  throws Exception {
		Integer numberUpperLimit = taskInfo.getNumberUpperLimit();
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfWeek(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getFirstDayOfWeek(), 7), "yyyy-MM-dd");
		if (pointTaskCompleteInfo.getNumberUpperLimit() == 0) {
			throw new ServiceOperationException("该任务完成的次数已达到上限");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqUserId", pointTaskCompleteInfo.getUserId());
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum*(numberUpperLimit-pointTaskCompleteInfo.getNumberUpperLimit()+1)) {
			throw new ServiceOperationException("该操作次数不足");
		}
		// 更新该常规任务
		updatePointTask(pointTaskCompleteInfo, taskInfo);
	}
	
	private void completePointByMonthly(TaskInfo taskInfo, PointTaskCompleteInfo pointTaskCompleteInfo) throws Exception  {
		Integer numberUpperLimit = taskInfo.getNumberUpperLimit();
		String actionType = taskInfo.getActionType();
		Integer completeNum = taskInfo.getCompleteNum();
		BigDecimal completeMoney = taskInfo.getCompleteMoney();
		String firstDay = DateUtil.formatDate(DateUtil.getFirstDayOfMonth(), "yyyy-MM-dd");
		String endDay = DateUtil.formatDate(DateUtil.getDateAfterDays(DateUtil.getLastDayOfMonth(), 1), "yyyy-MM-dd");
		if (pointTaskCompleteInfo.getNumberUpperLimit() == 0) {
			throw new ServiceOperationException("该任务完成的次数已达到上限");
		}
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqActionType", actionType);
		params.put("eqUserId", pointTaskCompleteInfo.getUserId());
		params.put("gtCreateTime", firstDay);
		params.put("ltCreateTime", endDay);
		params.put("eqOpenPlatformId", taskInfo.getOpenPlatformId());
		if (completeMoney != null && completeMoney.compareTo(new BigDecimal("0.00")) == 1) {
			params.put("geMoney", completeMoney);
		}
		int count = actionLogDao.selectCountByMap(params);
		if (count < completeNum*(numberUpperLimit-pointTaskCompleteInfo.getNumberUpperLimit()+1)) {
			throw new ServiceOperationException("该操作次数不足");
		}
		// 更新该常规任务
		updatePointTask(pointTaskCompleteInfo, taskInfo);
	}
	
	/**
	 * 更新常规任务
	 * 
	 * @param taskCompleteId
	 */
	private void updatePointTask(PointTaskCompleteInfo pointTaskCompleteInfo, TaskInfo taskInfo)  throws Exception {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("eqId", pointTaskCompleteInfo.getId());
		params.put("eqStatus", TaskCompleteStatusEnum.FINISH.getId());
		if ((pointTaskCompleteInfo.getNumberUpperLimit() -1) == 0 ) {
			params.put("status", TaskCompleteStatusEnum.COMPLETED.getId());
		} else {
			params.put("status", TaskCompleteStatusEnum.PROCESSING.getId());
		}
		if ((pointTaskCompleteInfo.getNumberUpperLimit() -1) == 0) {
			params.put("numberUpperLimit", pointTaskCompleteInfo.getNumberUpperLimit() -1);
		} else {
			params.put("completeNum", 0);
			params.put("numberUpperLimit", pointTaskCompleteInfo.getNumberUpperLimit() -1);
		}
		params.put("lastDate", new Date());
		int count = pointTaskCompleteInfoDao.updateByMap(params);
		if (count < 1) {
			throw new ServiceOperationException("领取任务失败");
		}
		if (taskInfo.getGetStrategy() == TaskGetStrategyEnum.LIMITED.getId()) {
			Integer getNum = taskInfo.getGetNum()-1;
			taskInfo.setGetNum(getNum);
			if (getNum == 0) {
				taskInfo.setStatus(TaskActionStatusEnum.DELETED.getId());
			}
			taskInfoDao.update(taskInfo);
		}
	}
	
	/** 
	 * 动作完成登记操作
	 */
	@Override
	public Response completeAction(Request request)  throws Exception {
		DefaultResponse response = new DefaultResponse();
		try {
			ActionLogRequest actionLogRequest = (ActionLogRequest) request;
			String actionType = actionLogRequest.getActionType();
			BigDecimal money = actionLogRequest.getMoney();
			String remark = actionLogRequest.getRemark();
			Integer openPlatformId = actionLogRequest.getOpenPlatformId();
			if(StringUtil.isEmpty(money)){
				money = new BigDecimal(0);
			}
			Integer userId = actionLogRequest.getUserId();
			this.addActionLog(actionType, userId, money, remark, openPlatformId);
			// 更新任务状态
			givingAsyncHelper.autoUpdateTask(actionType, userId, openPlatformId);
		} catch (Exception e) {
			log.error("func[{}] request[{}] exception[{} - {}] desc[fail]",
					new Object[] { this.getClass().getName() +"."+Thread.currentThread().getStackTrace()[1].getMethodName(),
						request,e.getMessage(),Arrays.deepToString(e.getStackTrace()) });
			throw new ServiceOperationException("请求处理失败：" + e.getMessage());
		}
		return response;
	}
	
	private void addActionLog(String actionType, Integer userId, BigDecimal money, String remark, Integer openPlatformId){
		ActionLog actionLog = new ActionLog();
		actionLog.setActionType(actionType);
		actionLog.setMoney(money);
		actionLog.setUserId(userId);
		actionLog.setRemark(remark);
		actionLog.setOpenPlatformId(openPlatformId);
		actionLogDao.insert(actionLog);
	}
	
}
